﻿using MicroDb;
using MicroDb.Querys;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace System
{
    public class Mdb<T>
    {

        public readonly IQueryable<T> Query;

        private DBQueryProvider QueryProvider => (DBQueryProvider)Query.Provider;


        public SqlExecute Execute => QueryProvider.SqlExecute;

        /// <summary>
        /// 执行事物
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="func"></param>
        /// <returns></returns>
        public Task<TResult> DoTarn<TResult>(Func<TResult> func)
        {
            return Execute.DoTran(func);
        }
        /// <summary>
        /// 执行事物
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public Task DoTarn(Action func)
        {
            return Execute.DoTran(func);
        }


        /// <summary>
        /// 分布式事物
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public Task DoTarn(Action func, params IQueryable[] appendQueries)
        {
            var exes = QueryProvider.AppendSqlExecutes(appendQueries);
            Func<Task> append = () => exes[0].DoTran(func);
            for (int i = 1; i < exes.Length; i++)
            {
                append = () => exes[i].DoTran(() => append().Wait());
            }
            return append();
        }

        /// <summary>
        /// 分布式事物
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="func"></param>
        /// <param name="dbSource"></param>
        /// <returns></returns>
        public Task<TResult> DoTarn<TResult>(Func<TResult> func, params IQueryable[] appendQueries)
        {
            var exes = QueryProvider.AppendSqlExecutes(appendQueries);
            Func<Task<TResult>> append = () => exes[0].DoTran(func);
            for (int i = 1; i < exes.Length; i++)
            {
                append = () => exes[i].DoTran(() => append().GetAwaiter().GetResult());
            }
            return append();
        }

    }
}
